//
//  can_move.cpp
//  EnTT Pacman
//
//  Created by Indiana Kernick on 27/9/18.
//  Copyright © 2018 Indiana Kernick. All rights reserved.
//

#include "can_move.hpp"

#include "comp/house.hpp"
#include "util/dir_to_pos.hpp"
#include <entt/entity/registry.hpp>

bool canMove(
  entt::registry &reg,
  const MazeState &maze,
  const entt::entity e,
  const Pos pos,
  const Dir desiredDir
) {
  // 欲达坐标
  const Pos desiredPos = pos + toPos(desiredDir);
  // 判断该坐标是否越界
  if (maze.outOfRange(desiredPos)) {
    // The tunnel is the only place where playable space meets the edge of the map.
    // The movement system handles the tunnel
    // 左右越界可行，存在隧道需要判断
    // 因此地图设计要符合逻辑就必须在边界设置墙  隧道点设置为左右边界
    return desiredDir == Dir::left || desiredDir == Dir::right;
  }

  // just like we assumed the position of the tunnel, we're assuming the
  // orientation of the door to the ghost house. Once again, making the door
  // into an entity is probably a more robust but more complex solution.
  // I guess this is one of those "do as I say, not as I do" situations!
  // 获取欲达坐标代表的 元素
  const Tile desiredTile = maze[desiredPos];
  
  if (desiredTile == Tile::door) { // 为门的情况
    // 如果实体含有 EnterHouse 组件 并且 欲达方向是下 (具体行为是回家)
    if (reg.has<EnterHouse>(e) && desiredDir == Dir::down) {
      return true;
    }// 如果实体含有 LeaveHouse 组件 并且 欲达方向是上 (具体行为为出门)
     else if (reg.has<LeaveHouse>(e) && desiredDir == Dir::up) {
      return true;
    }
  } else if (desiredTile != Tile::wall) { // 不为墙的情况
    return true;
  }

  // 剩余情况均不允许
  return false;
}
